import { Injectable, OnModuleInit } from "@nestjs/common";
import axios from "axios";
import { AppGateway } from "../app/app.gateway";
import { FSWatcher, watch } from "chokidar";
import * as path from "node:path";
import { instanceUrl, password, seriesUrl, studyUrl, username } from "../config/config.json";


const chokidar = require("chokidar");
const fs = require("fs");

interface reqType {
  scanId: number | string,
  scoutId: any
  watchFilePath: string,
  totalImgCount: number,
  scanType: string,
}

@Injectable()
export class WatchFileService implements OnModuleInit {
  watchers: FSWatcher[] = [];
  helperMap = new Map();
  fileCountMap = new Map();
  scanIdMap = new Map();

  constructor(private readonly socketIoGateway: AppGateway) {
  }

  async onModuleInit(): Promise<any> {
    console.log("启动监听程序，等待监听的文件路径");
  }

  convert2Map(watchPathArr: reqType[]) {
    watchPathArr.map(eachParams => {
      const filePath = path.normalize(eachParams.watchFilePath);
      this.helperMap.set(filePath, {
        scanId: eachParams.scanId,
        scanType: eachParams.scanType,
        scoutId: eachParams.scoutId || "",
        totalImgCount: eachParams.totalImgCount
      });
      this.fileCountMap.set(filePath, 0);
      if (this.scanIdMap.has(eachParams.scanId) && eachParams.scoutId) {
        const scoutIds = this.scanIdMap.get(eachParams.scanId);
        scoutIds.push(eachParams.scoutId);
      } else if (!this.scanIdMap.has(eachParams.scanId) && eachParams.scoutId) {
        this.scanIdMap.set(eachParams.scanId, []);
      }
    });
    console.log(`map信息为:${JSON.stringify(this.helperMap.keys())}`);
  }

  async addNewListen(watchParamsArr: reqType[]): Promise<any> {
    this.convert2Map(watchParamsArr);
    if (this.watchers.length > 0) {
      try {
        this.watchers.map(async (watcher) => {
          await watcher.close();
        });
        this.watchers = [];
      } catch (err) {
        console.log(err);
      }
    }

    watchParamsArr.map(async (watchParams) => {
      const watcher = chokidar.watch(watchParams.watchFilePath, {
        persistent: false,
        ignoreInitial: true
      });

      watcher.on("add", async (eventPath) => {
        console.log("监测到地址：", eventPath, ",发生变化：", "add");
        const parentPath = path.normalize(watchParams.watchFilePath);
        const { scanId, totalImgCount, scoutId } = this.helperMap.get(parentPath);
        const fileCount = this.fileCountMap.get(parentPath);
        this.fileCountMap.set(parentPath, fileCount + 1);
        let finishFlag = false
        if (fileCount + 1 === totalImgCount) {
          finishFlag =  this.checkRelateScanFinished(scanId);
        }
        setTimeout(async () => {
          const { ParentStudy, ParentSeries } = await this.upload(eventPath);
          const uids = await this.getStudyAndSeriesUID({ ParentStudy, ParentSeries });
          const msg = {
            scanId: scanId,
            scoutId: scoutId,
            imageIds: uids,
            totalImgCount,
            currentCount: fileCount + 1,
            currentScanIdFinish:finishFlag
          };
          console.log(`向前端发出消息:${JSON.stringify(msg)}`);
          this.socketIoGateway.sendDicomMsg(msg);
        }, 1000);
      });
      this.watchers.push(watcher);
    });

  }

  checkRelateScanFinished(scanId) {
    const scoutIds = this.scanIdMap.get(scanId);
    return scoutIds.every(scoutId => {
      const imgCounts = this.fileCountMap.get(scoutId);
      return imgCounts.currentCount + 1 === imgCounts.totalImgCount;
    });
  }

  private async upload(path1) {
    try {
      const dicomData = fs.readFileSync(path1);
      const res = await axios({
        method: "post",
        url: instanceUrl,
        data: dicomData,
        auth: {
          username: username,
          password: password
        },
        headers: {
          "Content-Type": "application/dicom"
        }
      });
      console.log("上传成功");
      const { ParentStudy, ParentSeries } = res.data;
      return { ParentStudy, ParentSeries };
    } catch (e) {
      console.error("DICOM文件上传失败:", e);
    }
  }

  private async getStudyAndSeriesUID({ ParentStudy, ParentSeries }) {
    const res = await axios({
      method: "get",
      url: studyUrl + `/${ParentStudy}`,
      auth: {
        username: username,
        password: password
      }
    });
    const res1 = await axios({
      method: "get",
      url: seriesUrl + `/${ParentSeries}`,
      auth: {
        username: username,
        password: password
      }
    });

    const studyUID = res.data.MainDicomTags.StudyInstanceUID;
    const seriesUID = res1.data.MainDicomTags.SeriesInstanceUID;
    return {
      studyUID,
      seriesUID
    };
  }
}
